#include <stdio.h>
#include <math.h>
#include "sprite.h"
#include "game.h"
#include "view.h"
#include "player.h"
#include "particle.h"
#include "databank.h"
#include "background.h"

void ViewModule::setup(void)
{
    buf = create_bitmap(SCREEN_W,SCREEN_H);

    plTmp = create_bitmap(data->sprites->player->w,
            data->sprites->player->h);

    cfg = data->getconfig();
}

void ViewModule::paint(GameModule *game)
{
    // First draw background.. obviously
    draw_sprite(buf, data->getBackground()->getBackground(), 0,0);

    // Draw all particles
    std::list<Particle *> *parts = data->getParticles();
    int particleCount = data->getParticles()->size();
    for (std::list<Particle *>::iterator i = parts->begin(); 
            i != parts->end(); i++)
    {
        double *pos = (*i)->g->position;
        putpixel(buf, int(pos[0]), int(pos[1]), (*i)->color);

        if(cfg->whiteParticles && particleCount <= 30)
            circle(buf, int(pos[0]), int(pos[1]), 1, makecol(255,255,255));
    }

    // Draw all centers
    /*std::vector<Zone *> *zones = data->getBackground()->getZones();
      for (std::vector<Zone *>::iterator i = zones->begin(); i != zones->end(); i++) {
      int col;

      if((*i)->getCenter()->mass <= double(cfg->physPartitionRes*cfg->physPartitionRes))
      col = 192;
      else col = 192.0 *(1.0 / ((*i)->getCenter()->mass / double(cfg->physPartitionRes*cfg->physPartitionRes)));

      circlefill(buf, (*i)->getCenter()->pos[0], (*i)->getCenter()->pos[1], 2, makecol(255-col,255-col,0));
      }*/

    // Draw all shots
    std::list<Shot *> *shots = data->getShots();
    for (std::list<Shot *>::iterator i = shots->begin();
            i != shots->end(); i++)
    {
        double *pos = (*i)->g->position;
        BITMAP *tmpShot = (*i)->getPicture();

        if (tmpShot != NULL) {
            double *vel = (*i)->g->velocity;
            double rad = atan2(vel[1], vel[0]);
            int degrees = rad * 128.0 / PIE;

            rotate_sprite(buf, tmpShot, int(pos[0]) - tmpShot->w/2,
                    int(pos[1]) - tmpShot->h/2, ftofix(degrees));     
        } else {
            putpixel(buf, int(pos[0]), int(pos[1]), makecol(255,0,0));
            putpixel(buf, int(pos[0]) + 1, int(pos[1]), makecol(255,0,0));
            putpixel(buf, int(pos[0]) - 1, int(pos[1]), makecol(255,0,0));
            putpixel(buf, int(pos[0]), int(pos[1]) + 1, makecol(255,0,0));
            putpixel(buf, int(pos[0]), int(pos[1]) - 1, makecol(255,0,0));
        }
    }

    // Draw interface background
    // Probably would be a nice thing if this was a bitmap
    // And if we didn't use a magic number here, I'd be pleased
    if(game->gameType != GAME_DEMO)
        rectfill(buf,0, SCREEN_H-64, SCREEN_W, SCREEN_H, makecol(64,64,64));

    // Draw players
    for (int i = 0; i < data->getPlayerSize(); i++) {
        Player *p = data->getPlayer(i);
        double *pos;

        if(p->getHP() <= 0) continue;

        // Drawing the player sprite
        pos = p->getPos();
        BITMAP *ship = p->getBitmap();
        draw_sprite(buf, ship, int(pos[0])-ship->w/2,
                int(pos[1])-ship->h/2);

        // Render player interface
        if(i == game->curPlayer && game->turnStatus != TURN_PARTICLE) {
            p->getInterface()->render(buf, p, data);
        }

        double mp[2] = {mouse_x,mouse_y};
        if(p->testCollision(mp)) {
            circle(buf, mouse_x, mouse_y, 4, makecol(255,255,255));
        } else {
            circle(buf, mouse_x, mouse_y, 3, makecol(192,192,192));
        }

        // Draw health for player
        int col = (i==game->curPlayer)
            ? makecol(255,64,64) : makecol(192,192,192);
        textprintf_ex(buf, font, (SCREEN_W*3)/4,
                SCREEN_H-64+1+15*i, col, -1, "Player %d", i+1);
        int x, y, w, h;
        x = (SCREEN_W*3)/4 + text_length(font, "Player 0")+5;
        y = SCREEN_H-64+1+15*i;
        w = 104;
        h = 12;
        rectfill(buf, x,y,x+w,y+h, 0);

        x += 2; // Slight offset for bar
        // Total width of bar is related to health
        w = int(double(p->getHP())/double(cfg->playerHealth)*100.0);
        rectfill(buf, x,y+2,x+w,y+h-2, makecol(255,0,0));
    }

    // Draw other information
    if(game->gameType != GAME_DEMO) {
        switch(game->turnStatus) {
            // Use loaded font here later
            case TURN_PLAYER:
                textprintf_ex(buf, font, SCREEN_W/2, SCREEN_H-64+1,
                        makecol(255,255,255), -1, "Turn: Player");
                break;
            case TURN_WEAPON:
                textprintf_ex(buf, font, SCREEN_W/2, SCREEN_H-64+1,
                        makecol(255,255,255), -1, "Turn: Weapon");
                break;
            case TURN_PARTICLE:
                textprintf_ex(buf, font, SCREEN_W/2, SCREEN_H-64+1,
                        makecol(255,255,255), -1,
                        "Turn: Particle (%d left)", particleCount);
                break;
            case TURN_SHOT:
                textprintf_ex(buf, font, SCREEN_W/2, SCREEN_H-64+1,
                        makecol(255,255,255), -1, "Turn: Shot");
                break;
        }

        blit(buf,screen,0,0,0,0,buf->w,buf->h);
        clear_bitmap(buf);
    }
}
